package com.anivia.common.web.config.desensitization;

import cn.hutool.core.util.DesensitizedUtil;
import com.anivia.common.core.enums.DesensitizedTypeEnum;
import com.anivia.common.web.annotation.DesensitizationField;
import com.anivia.common.web.model.vo.DesensitizedVO;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.Objects;


/**
 * 脱敏过滤器
 *
 * @author wangj
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public final class DesensitizationSerializer extends JsonSerializer<String> implements ContextualSerializer {
    /**
     * 脱敏类型
     */
    private DesensitizedTypeEnum type;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (ObjectUtils.isEmpty(value)) {
            return;
        }
        String val = switch (type) {
            case FIXED_PHONE -> DesensitizedUtil.fixedPhone(value);
            case PHONE -> DesensitizedUtil.mobilePhone(value);
            case ID_CARD -> DesensitizedUtil.idCardNum(value, 1, 2);
            case CHINESE_NAME -> DesensitizedUtil.chineseName(value);
            default -> value;
        };
        //修改数据
        gen.writeString(val);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            // 判断数据类型是否为String类型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                // 获取定义的注解
                DesensitizationField desensitization = beanProperty.getAnnotation(DesensitizationField.class);
                // 为null
                if (desensitization == null) {
                    desensitization = beanProperty.getContextAnnotation(DesensitizationField.class);
                }
                // 不为null
                if (desensitization != null) {
                    // 创建定义的序列化类的实例并且返回，入参为注解定义的type,开始位置，结束位置。
                    // 判断是否开启了脱敏开关
                    DesensitizedVO desensitizedVO = DataDesensitizationContext.get();
                    if (!desensitizedVO.isOpenDesensitization()
                            || !desensitizedVO.getDescensitizationList().contains(desensitization.type())) {
                        return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
                    }
                    return new DesensitizationSerializer(desensitization.type());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}
